package vn.cuhanh.fragment;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;

import vn.cuhanh.BaseActivity;
import vn.cuhanh.MainActivity;
import vn.cuhanh.R;
import vn.cuhanh.bean.Minigame;
import vn.cuhanh.utils.HelperFunc;
import vn.cuhanh.utils.ViewHelper;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.util.Log;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MinigameFragment extends BasicFragment {
	private static String GA_CATEGORY = "minigame_fragment";

	public static int createTimer = 0;
	public static int onTickCounter = 0;
	private View view;
	private ArrayList<Minigame> gamesInfo;
	private CountDownTimer timer;
	private MinigameAdapter adapter;
	private GridView gridGames;
	private Handler handler;
	private Minigame clickedGame;
	private View noNetworkScreen;
	private View loadingScreen;
	private LinearLayout contentWrapper;

	public static MinigameFragment newInstance(Context ctx) {
		return new MinigameFragment(ctx);
	}

	public MinigameFragment(Context ctx) {
		super(ctx);
		handler = new Handler();
	}

	public MinigameFragment() {
		super();
		handler = new Handler();
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onPause() {
		super.onPause();
	}

	@Override
	public void onDestroy() {

		super.onDestroy();
	}
	
	public void refreshGridView() {
		GridView gridGames = (GridView) this.view.findViewById(R.id.mini_game_grid_games);
		gridGames.invalidate();
	}
	
	public void destroyTimer(){
		if(timer != null) {
			timer.cancel();
		}
	}
	
	public void initGridGames(ArrayList<Minigame> listGames){
		this.gamesInfo = listGames;
		timer = null;
		this.adapter = new MinigameAdapter(ctx, R.layout.minigame_list_item, this.gamesInfo);
		gridGames = (GridView) this.view.findViewById(R.id.mini_game_grid_games);
		gridGames.setAdapter(adapter);
	}
	public int currentGameId = -1;
	public int timeLeft = 0;
	public Calendar localCreatedMinigame;
	public int secondUntilFinish = 0;
	public ArrayList<Minigame> parseGameList(JSONArray gamesInfo) {
		ArrayList<Minigame> result = new ArrayList<Minigame>();
		for (int i = 0; i < gamesInfo.length(); i++) {
			try {
				JSONObject gameInfo = gamesInfo.getJSONObject(i);
				int id = gameInfo.getInt("id");
				result.add(new Minigame(id, gameInfo.getString("name"), gameInfo.getInt("score"), gameInfo.getInt("duration"), gameInfo.getInt("type"), gameInfo.getString("image"), gameInfo.getInt("status")));
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}
	
	public void showNoData() {
		contentWrapper.setVisibility(View.GONE);
		noNetworkScreen.setVisibility(View.VISIBLE);
		loadingScreen.setVisibility(View.GONE);
	}
	
	public void showLoadingScreen() {
		ViewHelper.initLoadingFrame(ctx, loadingScreen);
		loadingScreen.setVisibility(View.VISIBLE);
		contentWrapper.setVisibility(View.GONE);
		noNetworkScreen.setVisibility(View.GONE);
	}
	
	public void loadMinigameFromSv(){
		Thread getMinigameThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				final String response = HelperFunc.getDataFromSv(ctx.getResources().getString(R.string.getMinigameUrl) + MainActivity.username);
				Log.d("minigame", String.valueOf(response));
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						try {
							if(response == null) {
								showNoData();
								return;
							}
							contentWrapper.setVisibility(View.VISIBLE);
							noNetworkScreen.setVisibility(View.GONE);
							loadingScreen.setVisibility(View.GONE);
							
							JSONObject jsonResponse = new JSONObject(response);
							currentGameId = jsonResponse.getInt("currentId");
							timeLeft = jsonResponse.getInt("timeLeft");
							localCreatedMinigame = Calendar.getInstance();
							JSONArray games = jsonResponse.getJSONArray("allActions");
							initGridGames(parseGameList(games));
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							HelperFunc.readStackTrace(e);
						}
					}
				});
			}
		});
		showLoadingScreen();
		getMinigameThread.start();
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		try {
			view = inflater.inflate(R.layout.minigame, null);
			if (ctx == null || view == null) {
				if (isAdded()) {
					ctx = getActivity();
				} else {
					return view;
				}
			}
			contentWrapper = (LinearLayout)view.findViewById(R.id.minigame_content_wrapper);
			loadingScreen = view.findViewById(R.id.loadingScreen);
			noNetworkScreen = view.findViewById(R.id.minigame_no_network);
			noNetworkScreen.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					loadMinigameFromSv();
				}
			});
			if(gamesInfo == null || gamesInfo.isEmpty()) {
				loadMinigameFromSv();
			} else {
				initGridGames(gamesInfo);
			}
			// manually start loading stuff in the first tab
			return view;
		} catch (InflateException e) {
			HelperFunc.readStackTrace(e);
		} catch (Exception e) {
			HelperFunc.readStackTrace(e);
		}
		return null;
	}
	
	@Override
	public void onResume() {
		super.onResume();
		BaseActivity.updateDndScore(view);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		setRetainInstance(true);
	}
	
	public void removeMinigame(Minigame minigame) {
		HelperFunc.showSimpleAlertDialog(ctx, null, ctx.getResources().getString(R.string.minigame_game_not_exist).replace("minigame_name", minigame.getName()), ctx.getResources().getString(R.string.bt_ok_title), null, null, null, true);
		gamesInfo.remove(minigame);
		adapter.setGamesInfo(gamesInfo);
		adapter.notifyDataSetChanged();
	}
	
	public class MinigameAdapter extends ArrayAdapter<Minigame> {
		private List<Minigame> gamesInfo;

		public MinigameAdapter(Context context, int textViewResourceId,
				List<Minigame> objects) {
			super(context, textViewResourceId, objects);
			// TODO Auto-generated constructor stub
			this.setGamesInfo(objects);
			this.getCount();
		}
		
		@Override
		public int getCount() {
			return this.getGamesInfo().size();
		}
		
		/**
		 * 
		 * @param v
		 * @param timeLeft
		 */
		public void refreshCountdown(int timeLeft, final int position) {
			if(timeLeft < 0) {
				timeLeft = 0;
			}
			if(timer != null) { //timer must be destroy before init new timer
				return;
			}
			Log.d("refreshCountdown", "position: " + position);
			createTimer++;
			Log.d("minigame", "Timeleft: " + timeLeft);
			timer = new CountDownTimer(timeLeft * 1000, 1000) {
				
				public void onTick(long millisUntilFinished) {
					secondUntilFinish = (int) (millisUntilFinished / 1000);
					adapter.notifyDataSetChanged();
					Log.d("minigame", "onTick: " + onTickCounter + " position: " + position + " text: " + ctx.getResources().getString(R.string.next_click) +": " 
							+ HelperFunc.secondToTime(ctx, secondUntilFinish));
				}
				
				public void onFinish() {
					secondUntilFinish = 0;
					adapter.notifyDataSetChanged();
					Log.d("refreshCountdown", "finish position: " + position);
				}
			}.start();
		}
		
		public void showNoNetworkDialog(final View v) {
			AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
					ctx);
	 
				// set title
				alertDialogBuilder.setTitle(null);
				// set dialog message
				alertDialogBuilder
					.setMessage(R.string.no_network_retry)
					.setCancelable(true)
					.setPositiveButton(R.string.bt_ok_title,new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,int id) {
							// if this button is clicked, close
							// current activity
							try {
								v.callOnClick();
							} catch (NoSuchMethodError e) {
								// TODO: handle exception
							}
						}
					  });
	 
				// create alert dialog
				AlertDialog alertDialog = alertDialogBuilder.create();
 
				// show it
				alertDialog.show();
		}
		
		public void showClickMinigameSuccessDialog(String title, int score) {
			AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
					ctx);
	 
				// set title
				alertDialogBuilder.setTitle(null);
				String message = ctx.getResources().getString(R.string.minigame_click_success);
				// set dialog message
				alertDialogBuilder
					.setMessage(message.replace("minigame_name", title).replace("minigame_score", String.valueOf(score)))
					.setCancelable(true)
					.setPositiveButton(R.string.bt_ok_title, null);//,new DialogInterface.OnClickListener() {
	 
				// create alert dialog
				AlertDialog alertDialog = alertDialogBuilder.create();
 
				// show it
				alertDialog.show();
		}
		
		@Override
		public View getView(final int position, View v, ViewGroup parent) {
			if(v == null) {
				LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = inflater.inflate(R.layout.minigame_list_item, null);
			}
			final Minigame gameInfo = this.getGamesInfo().get(position);
			TextView name = (TextView)v.findViewById(R.id.minigame_item_name);
			name.setText(gameInfo.getName());
			ImageView minigameImage = (ImageView)v.findViewById(R.id.minigame_item_image);
			UrlImageViewHelper.setUrlDrawable(minigameImage, gameInfo.getImageUrl());
			TextView score = (TextView)v.findViewById(R.id.minigame_item_score);
			score.setText("+ " + gameInfo.getScore() + " " + this.getContext().getResources().getString(R.string.diem_nang_dong_viet_tat));
			if(gameInfo.getStatus() == -1) { //finished
				TextView txtTimeLeft = (TextView)v.findViewById(R.id.minigame_item_timeleft);
				View wrapper = v.findViewById(R.id.content_wrapper);
				wrapper.setBackgroundColor(0xFFDCDCDC);
				txtTimeLeft.setText(R.string.minigame_finished);
				v.setClickable(false);
				return v;
			}
			if(gameInfo.getStatus() == 0) { //not ready yet
				View wrapper = v.findViewById(R.id.content_wrapper);
				TextView txtTimeLeft = (TextView)v.findViewById(R.id.minigame_item_timeleft);
				txtTimeLeft.setText("");
				wrapper.setBackgroundColor(0xFFDCDCDC);
				v.setClickable(false);
				Log.d("minigame", "getView position " + position + " status: " + gameInfo.getStatus() + " returned.");
				return v;
			}
			if(gameInfo.getStatus() != 1) {
				HelperFunc.readStackTrace(new Exception("Minigame invalid status code: " + gameInfo.getStatus()));
				return v;
			}
			Log.d("minigame", "getView position " + position + " status: " + gameInfo.getStatus());
			if(localCreatedMinigame == null) {
				return v;
			}
			long now = Calendar.getInstance().getTimeInMillis();
			long created = localCreatedMinigame.getTimeInMillis();
			View wrapper = v.findViewById(R.id.content_wrapper);
			if(secondUntilFinish > 0) {
				wrapper.setBackgroundColor(0xFFDCDCDC);
				v.setClickable(false);
				TextView txtTimeLeft = (TextView)v.findViewById(R.id.minigame_item_timeleft);
				txtTimeLeft.setText(ctx.getResources().getString(R.string.next_click) +": " 
						+ HelperFunc.secondToTime(ctx, secondUntilFinish));
			} else {
				wrapper.setBackgroundColor(0xFFFFFFFF);
				v.setClickable(true);
				TextView txtTimeLeft = (TextView)v.findViewById(R.id.minigame_item_timeleft);
				txtTimeLeft.setText("");
				v.setOnClickListener(new OnClickListener() {
					
					@Override
					public void onClick(View view) {
						// TODO Auto-generated method stub
						HelperFunc.trackEvent(ctx, GA_CATEGORY, "minigame_item_click", "minigame_item_click");
						final View v = view;
						v.setClickable(false);
						Thread thread = new Thread(new Runnable() {
							
							@Override
							public void run() {
								// TODO Auto-generated method stub
								try {
									ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
									params.add(new BasicNameValuePair("userName", MainActivity.username));
									params.add(new BasicNameValuePair("actionId", String.valueOf(gameInfo.getId())));
									String response = HelperFunc.getDataFromSv(ctx.getResources().getString(R.string.minigameClickHandlerUrl), params);
									if(response == null || response.isEmpty()) {
										handler.post(new Runnable() {
											
											@Override
											public void run() {
												// TODO Auto-generated method stub
												showNoNetworkDialog(v);
											}
										});
										return;
									}
									final JSONObject jsonResponse = new JSONObject(response);
									int result = jsonResponse.getInt("result");
									if(result == 0) {
										handler.post(new Runnable() {
											
											@Override
											public void run() {
												// TODO Auto-generated method stub
												removeMinigame(gameInfo);
											}
										});
										return;
									}
									if(result == 1) {
										timeLeft = jsonResponse.getInt("timeLeft");
										currentGameId = jsonResponse.getInt("currentId");
										localCreatedMinigame = Calendar.getInstance();
										final int totalScore = jsonResponse.getInt("totalScore");
										if(jsonResponse.has("remainScore") && !jsonResponse.isNull("remainScore")) {
											AwardFragment.remainDndScore = jsonResponse.getInt("remainScore");
										}
										handler.post(new Runnable() {
											
											@Override
											public void run() {
												// TODO Auto-generated method stub
//											updateMinigameCreatedTime(gameInfo, timeLeft);
												timer = null;
												refreshCountdown(timeLeft, position);
												BaseActivity.updateTotalScore(ctx, totalScore, MinigameFragment.this.view);
												showClickMinigameSuccessDialog(gameInfo.getName(), gameInfo.getScore());
											}
										});
									}
									if(result == 1 || result == -3) {
										((Activity)ctx).runOnUiThread(new Runnable() {
											
											@Override
											public void run() {
												// TODO Auto-generated method stub
												try {
													initGridGames(parseGameList(jsonResponse.getJSONArray("allActions")));
												} catch (JSONException e) {
													// TODO Auto-generated catch block
													HelperFunc.readStackTrace(e);
												}
											}
										});
									}
								} catch (JSONException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (Exception e) {
									HelperFunc.readStackTrace(e);
								}
							}
						});
						thread.start();
					}
				});
			}
			int secDelta = (int)((now - created) / 1000);
			if(secDelta < 0) {
				secDelta = 0;
			}
			refreshCountdown(timeLeft - secDelta, position);
			return v;
		}

		public List<Minigame> getGamesInfo() {
			return gamesInfo;
		}

		public void setGamesInfo(List<Minigame> gamesInfo) {
			this.gamesInfo = gamesInfo;
		}
	}
}
